package com.dms.modules.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dms.modules.product.dto.ProductSearchDTO;
import com.dms.modules.product.entity.Product;
import com.dms.modules.product.entity.ProductCategory;
import com.dms.modules.product.service.ProductCategoryService;
import com.dms.modules.product.service.ProductSearchService;
import com.dms.modules.product.service.ProductService;
import com.dms.modules.product.vo.CategoryVO;
import com.dms.modules.product.vo.ProductSearchVO;
import com.dms.modules.product.vo.ProductVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ProductSearchServiceImpl implements ProductSearchService {

    @Autowired
    private ProductService productService;

    @Autowired
    private ProductCategoryService categoryService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String SEARCH_HISTORY_KEY = "search:history:";
    private static final String HOT_SEARCH_KEY = "search:hot";

    @Override
    public ProductSearchVO search(ProductSearchDTO searchDTO) {
        // 保存搜索历史
        if (searchDTO.getKeyword() != null) {
            saveSearchHistory(searchDTO.getUserId(), searchDTO.getKeyword());
            // 更新热门搜索
            redisTemplate.opsForZSet().incrementScore(HOT_SEARCH_KEY, searchDTO.getKeyword(), 1);
        }

        // 构建查询条件
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getStatus, 1);  // 只查询上架商品
        
        // 关键词搜索
        if (searchDTO.getKeyword() != null && !searchDTO.getKeyword().trim().isEmpty()) {
            wrapper.and(w -> w.like(Product::getName, searchDTO.getKeyword())
                    .or()
                    .like(Product::getDetail, searchDTO.getKeyword()));
        }
        
        // 分类筛选
        if (searchDTO.getCategoryId() != null) {
            wrapper.eq(Product::getCategoryId, searchDTO.getCategoryId());
        }
        
        // 价格区间
        if (searchDTO.getMinPrice() != null) {
            wrapper.ge(Product::getPrice, searchDTO.getMinPrice());
        }
        if (searchDTO.getMaxPrice() != null) {
            wrapper.le(Product::getPrice, searchDTO.getMaxPrice());
        }
        
        // 店铺筛选
        if (searchDTO.getShopId() != null) {
            wrapper.eq(Product::getMerchantId, searchDTO.getShopId());
        }
        
        // 特价商品
        if (searchDTO.getOnlySpecial()) {
            wrapper.apply("price < original_price");
        }
        
        // 库存筛选
        if (searchDTO.getHasStock() != null && searchDTO.getHasStock() == 1) {
            wrapper.gt(Product::getStock, 0);
        }
        
        // 排序
        if (searchDTO.getOrderBy() != null) {
            switch (searchDTO.getOrderBy()) {
                case "sales_desc":
                    wrapper.orderByDesc(Product::getSales);
                    break;
                case "price_asc":
                    wrapper.orderByAsc(Product::getPrice);
                    break;
                case "price_desc":
                    wrapper.orderByDesc(Product::getPrice);
                    break;
                case "create_time_desc":
                    wrapper.orderByDesc(Product::getCreateTime);
                    break;
                default:  // 综合排序
                    wrapper.orderByDesc(Product::getSales, Product::getViewCount);
            }
        } else {
            wrapper.orderByDesc(Product::getSales, Product::getViewCount);
        }

        // 分页查询
        Page<Product> page = new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize());
        IPage<Product> productPage = productService.page(page, wrapper);

        // 构建返回结果
        ProductSearchVO searchVO = new ProductSearchVO();
        searchVO.setTotal(productPage.getTotal());
        searchVO.setPages(productPage.getPages());
        searchVO.setCurrent(productPage.getCurrent());
        searchVO.setSize(productPage.getSize());
        searchVO.setHasNext(productPage.getCurrent() < productPage.getPages());

        // 转换商品列表
        List<ProductVO> productVOList = productPage.getRecords().stream()
            .map(this::convertToProductVO)
            .collect(Collectors.toList());
        searchVO.setProducts(productVOList);

        // 获取相关分类
        searchVO.setRelatedCategories(getRelatedCategories(productPage.getRecords()));

        return searchVO;
    }

    @Override
    public List<String> getSearchSuggestions(String keyword, Integer limit) {
        // 从热门搜索中获取建议
        Set<String> suggestions = redisTemplate.opsForZSet()
            .reverseRangeByScore(HOT_SEARCH_KEY, 0, Double.POSITIVE_INFINITY, 0, limit);
        return new ArrayList<>(suggestions != null ? suggestions : new ArrayList<>());
    }

    @Override
    public List<String> getSearchHistory(Long userId, Integer limit) {
        String key = SEARCH_HISTORY_KEY + userId;
        List<String> history = redisTemplate.opsForList().range(key, 0, limit - 1);
        return history != null ? history : new ArrayList<>();
    }

    @Override
    public void saveSearchHistory(Long userId, String keyword) {
        if (userId == null || keyword == null) {
            return;
        }
        String key = SEARCH_HISTORY_KEY + userId;
        redisTemplate.opsForList().leftPush(key, keyword);
        redisTemplate.opsForList().trim(key, 0, 9); // 只保留最近10条记录
        updateHotSearch(keyword);
    }

    @Override
    public void clearSearchHistory(Long userId) {
        String key = SEARCH_HISTORY_KEY + userId;
        redisTemplate.delete(key);
    }

    @Override
    public List<String> getHotSearches(Integer limit) {
        Set<String> keywords = redisTemplate.opsForZSet()
            .reverseRange(HOT_SEARCH_KEY, 0, limit - 1);
        return new ArrayList<>(keywords != null ? keywords : new ArrayList<>());
    }

    @Override
    public void updateHotSearch(String keyword) {
        redisTemplate.opsForZSet().incrementScore(HOT_SEARCH_KEY, keyword, 1);
    }

    @Override
    public IPage<Product> searchMerchantProducts(ProductSearchDTO searchDTO, Integer status) {
        return productService.searchMerchantProducts(searchDTO, status);
    }

    @Override
    public IPage<Product> adminSearchProducts(ProductSearchDTO searchDTO, Integer auditStatus) {
        return productService.adminSearchProducts(searchDTO, auditStatus);
    }

    private ProductVO convertToProductVO(Product product) {
        ProductVO vo = new ProductVO();
        BeanUtils.copyProperties(product, vo);
        return vo;
    }

    private List<CategoryVO> getRelatedCategories(List<Product> products) {
        if (products == null || products.isEmpty()) {
            return new ArrayList<>();
        }

        // 获取所有相关分类ID
        Set<Long> categoryIds = products.stream()
            .map(Product::getCategoryId)
            .collect(Collectors.toSet());

        // 查询分类信息
        List<ProductCategory> categories = categoryService.listByIds(categoryIds);

        // 转换为VO
        return categories.stream()
            .map(category -> {
                CategoryVO vo = new CategoryVO();
                BeanUtils.copyProperties(category, vo);
                return vo;
            })
            .collect(Collectors.toList());
    }
} 